package com.testingedu.filter;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.testingedu.utils.StringUtils;

public abstract class ActionInvoke {
	private static final Log log = LogFactory.getLog(ActionInvoke.class);
	private static final String ENCODING_NAME = "UTF-8";
	public static final String PAGE_404 = "/error/404.jsp"; // 没有对应的请求
	public static final String PAGE_500 = "/error/500.jsp"; // 程序异常
	public static final String PAGE_ERROR = "/error/error.jsp";//错误通用页面
	protected static final String PREFIX = "_";
	protected String[] uris;
	protected HttpServletRequest request;
	protected HttpServletResponse response;
	protected ServletContext servletContext;
	/**
	 * 判断url(被'/'分隔为数组)的长度是否在某个范围内
	 * 
	 * @param length
	 * @return
	 */
	public boolean baseURISecurity(int length) {
		if (uris.length > length) {
			return false;
		}
		return true;
	}
	
	/**
	 * 将request和response设置到RequestContext中
	 * 
	 * @param clazz
	 *            action的Class实例
	 * @param action
	 *            action实例
	 */
	@SuppressWarnings("unchecked")
	public void setReqAndRespToAction(Class clazz, Object action) {
		try { // 忽略所有异常
			Method reqM = clazz.getMethod("setRequest",
					HttpServletRequest.class); // 将request和response设置到ResuestContext父类中
			Method respM = clazz.getMethod("setResponse",
					HttpServletResponse.class);
			Method conM = clazz.getMethod("setServletContext",
					ServletContext.class);
			reqM.invoke(action, request);
			respM.invoke(action, response);
			conM.invoke(action, servletContext);
		} catch (Exception e) {
			log.error("设置request、response、servletContext到RequestContext中失败：" + e);
		}
	}
	
	/**
	 * 自动编码处理
	 */
	public void autoEncoding() {
		try {
			request.setCharacterEncoding(ENCODING_NAME);
			response.setCharacterEncoding(ENCODING_NAME);
			response.setContentType("text/html; charset=UTF-8");
		} catch (UnsupportedEncodingException e) {
			log.error("自动编码失败：" + e);
		}
	}
	
	/**
	 * 将action中的bean注入到action中
	 * 
	 * @param clazz
	 *            action的Class实例
	 * @param action
	 *            action实例
	 * @param bean
	 *            bean实例
	 */
	@SuppressWarnings("unchecked")
	public void setBeanToAction(Class clazz, Object action, Object bean) {
		if (bean == null) {
			bean = parameters(request, action);
		}
		try { // 忽略任何异常
			if (bean != null) {
				Method beanM = clazz.getDeclaredMethod(StringUtils
						.getSetMethodName(bean.getClass().getSimpleName()),
						bean.getClass());
				beanM.invoke(action, bean); // 将bean设置到对应的action中
			}
		} catch (Exception e) {
		}
	}
	
	/**
	 * 自动封装参数，此处只实现了action对应的bean，如TUserAction，则只封装表单中对应的TUser属性
	 * 
	 * @param request
	 *            HttpServletRequest实例
	 * @param action
	 *            将要执行的action实例
	 * @return
	 */
	private Object parameters(HttpServletRequest request, Object action) {
		Object bean = this.newBean(action);
		try {
			BeanUtils.populate(bean, request.getParameterMap());
		} catch (Exception e) {
		}
		return bean;
	}
	
	/**
	 * 创建action所对应的bean
	 * 
	 * @param action
	 *            action实例
	 * @return
	 */
	public Object newBean(Object action) {
		String actionSimpleName = action.getClass().getSimpleName();
		String beanName = "com.testingedu.model."
				+ actionSimpleName.substring(0, actionSimpleName
						.lastIndexOf('A'));// 注意，此处使用了约定属成的策略获取到action所对应的bean全称
		Object bean = null;
		try {
			bean = Class.forName(beanName).newInstance();
		} catch (Exception e) {
		}
		return bean;
	}
	
	public abstract void invoke() throws Exception;
}
